-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): Fix XSS validation and separate URL validation #10424
Conversation
|
||
if (sanitized !== value) return false; | ||
|
||
return !URL_REGEX.test(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this should be a separate validator. Having a URL is not a XSS. I guess for backwards compat we could then include that validator also in places that are currently using the NoXss
, if they need that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree! Not sure why it was ever included.
@@ -0,0 +1,32 @@ | |||
import type { ValidationOptions, ValidatorConstraintInterface } from 'class-validator'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this file be somewhere else than under @/databases
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, not sure why but it has been like this since forever. Changed.
const entity = new Entity(); | ||
|
||
describe('Scripts and URLs', () => { | ||
const MALICIOUS_STRINGS = ['http://google.com', '<script src/>', 'www.domain.tld']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also <script>alert('xss')</script>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, thank you for addressing 👏 The comment about test.each
can also be done as a follow up
for (const str of URLS) { | ||
test(`should block ${str}`, async () => { | ||
entity.name = str; | ||
const errors = await validate(entity); | ||
expect(errors).toHaveLength(1); | ||
const [error] = errors; | ||
expect(error.property).toEqual('name'); | ||
expect(error.constraints).toEqual({ NoUrl: 'Potentially malicious string' }); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test.each
is made for cases like this:
for (const str of URLS) { | |
test(`should block ${str}`, async () => { | |
entity.name = str; | |
const errors = await validate(entity); | |
expect(errors).toHaveLength(1); | |
const [error] = errors; | |
expect(error.property).toEqual('name'); | |
expect(error.constraints).toEqual({ NoUrl: 'Potentially malicious string' }); | |
}); | |
} | |
test.each(['http://google.com', 'www.domain.tld'])( | |
'should block %s', async (str) => { | |
entity.name = str; | |
const errors = await validate(entity); | |
expect(errors).toHaveLength(1); | |
const [error] = errors; | |
expect(error.property).toEqual('name'); | |
expect(error.constraints).toEqual({ NoUrl: 'Potentially malicious string' }); | |
} | |
) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I've always found a simple loop more readable and easier to remember, for test.each
I always have to look up the syntax 😓 Is test.each
faster or better in some other way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point. Personally I find test.each
more readable :D There are subtle differences also, like mentioned in this SO comment
describe('Scripts', () => { | ||
const XSS_STRINGS = ['<script src/>', "<script>alert('xss')</script>"]; | ||
|
||
for (const str of XSS_STRINGS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same in this test suite
|
Test summaryRun details
Failures
This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Cloud |
This seems to be causing e2e tests to fail here 9bfc074 |
* master: fix(editor): Add workflow scopes when initializing workflow (#10455) feat(editor): Improve node label readability in new canvas (no-changelog) (#10432) fix(editor): Fix lazy loaded component not using suspense (no-changelog) (#10454) fix(editor): Buffer json chunks in stream response (#10439) refactor(editor): Remove `id` param from PATCH /me calls (no-changelog) (#10449) fix(core): Fix XSS validation and separate URL validation (#10424) fix(Respond to Webhook Node): Fix issue preventing the chat trigger from working (#9886) feat(editor): Add `registerCustomAction` to new canvas (no-changelog) (#10359)
Got released with |
# [1.56.0](https://github.com/netroy/n8n/compare/[email protected]@1.56.0) (2024-08-20) ### Bug Fixes * Better errors in Switch, If and Filter nodes ([n8n-io#10457](https://github.com/netroy/n8n/issues/10457)) ([aea82cb](aea82cb)) * **core:** Fix payload property in `workflow-post-execute` event ([n8n-io#10413](https://github.com/netroy/n8n/issues/10413)) ([d98e29e](d98e29e)) * **core:** Fix XSS validation and separate URL validation ([n8n-io#10424](https://github.com/netroy/n8n/issues/10424)) ([91467ab](91467ab)) * **core:** Use explicit types in configs to ensure valid decorator metadata ([n8n-io#10433](https://github.com/netroy/n8n/issues/10433)) ([2043daa](2043daa)) * **editor:** Add workflow scopes when initializing workflow ([n8n-io#10455](https://github.com/netroy/n8n/issues/10455)) ([b857c2c](b857c2c)) * **editor:** Buffer json chunks in stream response ([n8n-io#10439](https://github.com/netroy/n8n/issues/10439)) ([37797f3](37797f3)) * **editor:** Fix flaky mapping tests ([n8n-io#10453](https://github.com/netroy/n8n/issues/10453)) ([fc6d413](fc6d413)) * **editor:** Highlight matching type in filter component ([n8n-io#10425](https://github.com/netroy/n8n/issues/10425)) ([6bca879](6bca879)) * **editor:** Show item count in output panel schema view ([n8n-io#10426](https://github.com/netroy/n8n/issues/10426)) ([4dee7cc](4dee7cc)) * **editor:** Truncate long data pill labels in schema view ([n8n-io#10427](https://github.com/netroy/n8n/issues/10427)) ([1bf2f4f](1bf2f4f)) * Filter component - improve errors ([n8n-io#10456](https://github.com/netroy/n8n/issues/10456)) ([61ac0c7](61ac0c7)) * **Google Sheets Node:** Better error when column to match on is empty ([n8n-io#10442](https://github.com/netroy/n8n/issues/10442)) ([ce46bf5](ce46bf5)) * **Google Sheets Node:** Update name and hint for useAppend option ([n8n-io#10443](https://github.com/netroy/n8n/issues/10443)) ([c5a0c04](c5a0c04)) * **Google Sheets Node:** Update to returnAllMatches option ([n8n-io#10440](https://github.com/netroy/n8n/issues/10440)) ([f7fb02e](f7fb02e)) * **Invoice Ninja Node:** Fix payment types ([n8n-io#10462](https://github.com/netroy/n8n/issues/10462)) ([129245d](129245d)) * **n8n Form Trigger Node:** Show basic authentication modal on wrong credentials ([n8n-io#10423](https://github.com/netroy/n8n/issues/10423)) ([0dc3e99](0dc3e99)) * **OpenAI Node:** Throw node operations error in case of openAi client error ([n8n-io#10448](https://github.com/netroy/n8n/issues/10448)) ([0d3ed46](0d3ed46)) * Project Viewer always seeing a connection error when testing credentials ([n8n-io#10417](https://github.com/netroy/n8n/issues/10417)) ([613cdd2](613cdd2)) * Remove unimplemented Postgres credentials options ([n8n-io#10461](https://github.com/netroy/n8n/issues/10461)) ([17ac784](17ac784)) * Require mfa code to change email ([n8n-io#10354](https://github.com/netroy/n8n/issues/10354)) ([39c8e50](39c8e50)) * **Respond to Webhook Node:** Fix issue preventing the chat trigger from working ([n8n-io#9886](https://github.com/netroy/n8n/issues/9886)) ([9d6ad88](9d6ad88)) * Show input names when node has multiple inputs ([n8n-io#10434](https://github.com/netroy/n8n/issues/10434)) ([973956c](973956c)) ### Features * **core:** Support bidirectional communication between specific mains and specific workers ([n8n-io#10377](https://github.com/netroy/n8n/issues/10377)) ([d0fc9de](d0fc9de)) * **Facebook Graph API Node:** Update node to support API v18 - v20 ([n8n-io#10419](https://github.com/netroy/n8n/issues/10419)) ([e7ee10f](e7ee10f)) Co-authored-by: netroy <[email protected]>
https://linear.app/n8n/issue/PAY-1845